// Listener
callback = function( _, isAbort ) {
- // Was never called and is aborted or complete
- if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
-
- // Only called once
- callback = 0;
-
- // Do not keep as active anymore
- if ( handle ) {
- xhr.onreadystatechange = jQuery.noop;
- delete xhrs[ handle ];
- }
-
- // If it's an abort
- if ( isAbort ) {
- // Abort it manually if needed
- if ( xhr.readyState !== 4 ) {
- xhr.abort();
+ var status,
+ statusText,
+ responseHeaders,
+ responses,
+ xml;
+
+ // Firefox throws exceptions when accessing properties
+ // of an xhr when a network error occured
+ // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
+ try {
+
+ // Was never called and is aborted or complete
+ if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
+
+ // Only called once
+ callback = undefined;
+
+ // Do not keep as active anymore
+ if ( handle ) {
+ xhr.onreadystatechange = jQuery.noop;
+ delete xhrs[ handle ];
}
- } else {
- // Get info
- var status = xhr.status,
- statusText,
- responseHeaders = xhr.getAllResponseHeaders(),
- responses = {},
- xml = xhr.responseXML;
- // Construct response list
- if ( xml && xml.documentElement /* #4958 */ ) {
- responses.xml = xml;
- }
- responses.text = xhr.responseText;
-
- // Firefox throws an exception when accessing
- // statusText for faulty cross-domain requests
- try {
- statusText = xhr.statusText;
- } catch( e ) {
- // We normalize with Webkit giving an empty statusText
- statusText = "";
- }
+ // If it's an abort
+ if ( isAbort ) {
+ // Abort it manually if needed
+ if ( xhr.readyState !== 4 ) {
+ xhr.abort();
+ }
+ } else {
+ // Get info
+ status = xhr.status;
+ responseHeaders = xhr.getAllResponseHeaders();
+ responses = {};
+ xml = xhr.responseXML;
- // Filter status for non standard behaviors
- status =
- // Most browsers return 0 when it should be 200 for local files
- // Opera returns 0 when it should be 304
- // Webkit returns 0 for failing cross-domain no matter the real status
- !status ?
- // All: for local files, 0 is a success
- ( location.protocol === "file:" ? 200 : (
- // Webkit, Firefox: filter out faulty cross-domain requests
- !s.crossDomain || statusText ?
+ // Construct response list
+ if ( xml && xml.documentElement /* #4958 */ ) {
+ responses.xml = xml;
+ }
+ responses.text = xhr.responseText;
+
+ // Firefox throws an exception when accessing
+ // statusText for faulty cross-domain requests
+ try {
+ statusText = xhr.statusText;
+ } catch( e ) {
+ // We normalize with Webkit giving an empty statusText
+ statusText = "";
+ }
+
+ // Filter status for non standard behaviors
+ status =
+ // Most browsers return 0 when it should be 200 for local files
+ // Opera returns 0 when it should be 304
+ // Webkit returns 0 for failing cross-domain no matter the real status
+ !status ?
+ // All: for local files, 0 is a success
+ ( location.protocol === "file:" ? 200 : (
+ // Webkit, Firefox: filter out faulty cross-domain requests
+ !s.crossDomain || statusText ?
+ (
+ // Opera: filter out real aborts #6060
+ responseHeaders ?
+ 304 :
+ 0
+ ) :
+ // We assume 302 but could be anything cross-domain related
+ 302
+ ) ) :
(
- // Opera: filter out real aborts #6060
- responseHeaders ?
- 304 :
- 0
- ) :
- // We assume 302 but could be anything cross-domain related
- 302
- ) ) :
- (
- // IE sometimes returns 1223 when it should be 204 (see #1450)
- status == 1223 ?
- 204 :
- status
- );
-
- // Call complete
- complete( status, statusText, responses, responseHeaders );
+ // IE sometimes returns 1223 when it should be 204 (see #1450)
+ status == 1223 ?
+ 204 :
+ status
+ );
+ }
}
+ } catch( firefoxAccessException ) {
+ if ( !isAbort ) {
+ complete( -1, firefoxAccessException );
+ }
+ }
+
+ // Call complete if needed
+ if ( responses ) {
+ complete( status, statusText, responses, responseHeaders );
}
};
--- /dev/null
+<!DOCTYPE html>
+<html>
+<!--
+ Test for #8135
+
+ Thanks John Firebaugh for this test page based on his gist
+ https://gist.github.com/807090
+
+ Access this page through a web server, then stop said server and click the button.
+-->
+<head>
+ <title>
+ jQuery Network Error Test for Firefox
+ </title>
+ <style>
+ div { margin-top: 10px; }
+ </style>
+ <script src="../src/core.js"></script>
+ <script src="../src/support.js"></script>
+ <script src="../src/data.js"></script>
+ <script src="../src/queue.js"></script>
+ <script src="../src/attributes.js"></script>
+ <script src="../src/event.js"></script>
+ <script src="../src/sizzle/sizzle.js"></script>
+ <script src="../src/sizzle-jquery.js"></script>
+ <script src="../src/traversing.js"></script>
+ <script src="../src/manipulation.js"></script>
+ <script src="../src/css.js"></script>
+ <script src="../src/ajax.js"></script>
+ <script src="../src/ajax/jsonp.js"></script>
+ <script src="../src/ajax/script.js"></script>
+ <script src="../src/ajax/xhr.js"></script>
+ <script src="../src/effects.js"></script>
+ <script src="../src/offset.js"></script>
+ <script src="../src/dimensions.js"></script>
+ <script type="text/javascript">
+ $('button').live('click', function () {
+ $.ajax({
+ url: '/',
+ error: function() {
+ console.log( "abort", arguments );
+ }
+ }).abort();
+ $.ajax({
+ url: '/',
+ error: function() {
+ console.log( "complete", arguments );
+ }
+ });
+ return false;
+ })
+ </script>
+</head>
+<body>
+ <h1>
+ jQuery Network Error Test for Firefox
+ </h1>
+ <div>
+ This is a test page for
+ <a href="http://bugs.jquery.com/ticket/8135">
+ #8135
+ </a>
+ which was reported in Firefox when accessing properties
+ of an XMLHttpRequest object after a network error occured.
+ </div>
+ <div>Take the following steps:</div>
+ <ol>
+ <li>
+ make sure you accessed this page through a web server,
+ </li>
+ <li>
+ stop the web server,
+ </li>
+ <li>
+ open the console,
+ </li>
+ <li>
+ click this
+ <button>button</button>
+ ,
+ </li>
+ <li>
+ wait for both requests to fail.
+ </li>
+ </ol>
+ <div>
+ Test passes if you get two log lines:
+ <ul>
+ <li>
+ the first starting with "abort",
+ </li>
+ <li>
+ the second starting with "complete",
+ </li>
+ </ul>
+ </div>
+ <div>
+ Test fails if the browser notifies an exception.
+ </div>
+</body>
+</html>
\ No newline at end of file